package nio.timeServerTest;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2017/3/14 0014.
 */
public class ClientServer implements Runnable{

    private String host = "127.0.0.1";

    private Integer port = 8110;

    private Selector selector;

    private SocketChannel socketChannel;

    private Boolean stop;

    private Integer id;

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            executorService.submit(new ClientServer(i));
        }
    }

    public ClientServer(Integer id){
        try {
            this.id = id;
            this.stop = false;
            selector = Selector.open();
            socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(false);
        }catch (Exception e){
            e.printStackTrace();
            System.exit(1);
        }
    }

    private void handleSelectorKey(SelectionKey selectionKey){
        try {
            if(selectionKey.isValid()){
                SocketChannel channel = (SocketChannel)selectionKey.channel();
                if(selectionKey.isConnectable()){
                    if(channel.finishConnect()){
                        channel.register(selector,SelectionKey.OP_READ);
                        doWrite(channel);
                    }else{
                        System.out.println("connect failed");
                    }
                }

                if(selectionKey.isReadable()){
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int readByte = socketChannel.read(buffer);
                    if(readByte > 0){
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        buffer.get(bytes);
                        String content = new String(bytes);
                        System.out.println(id + "---recv :" +  content);

                        doWrite(channel);
                        Thread.sleep(1000);
                    }
                }



            }
        }catch (IOException io){
            try {
                if(selectionKey.channel() != null){
                    selectionKey.channel().close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (Exception e) {
            System.out.println("connect failed");
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            if(socketChannel.connect(new InetSocketAddress(host,port))){
                socketChannel.register(selector, SelectionKey.OP_READ);
                doWrite(socketChannel);

            }else{
                socketChannel.register(selector,SelectionKey.OP_CONNECT);
            }

            while (!stop){
                selector.select(1000);
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
                if(selectionKeyIterator.hasNext()){
                    SelectionKey selectionKey = selectionKeyIterator.next();
                    selectionKeyIterator.remove();
                    handleSelectorKey(selectionKey);
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void doWrite(SocketChannel socketChannel) throws IOException {
        byte[] req =("thread" + id + "query time").getBytes();
        ByteBuffer byteBuffer = ByteBuffer.allocate(req.length);
        byteBuffer.put(req);
        byteBuffer.flip();
        socketChannel.write(byteBuffer);
    }
}
